/* Moduł zapewniający obsługę dostępu do łącza. Ma zbierać ramki od sterownika,
 * przeprowadzać symulację dostępu CSMA/CA i z odpowiednim opóźnieniem zwraca
 * ramki, które powinny być wysłane do intefejsów w obrębie węzła fizycznej
 * sieci. */

#ifndef HEADER_LINK
#define HEADER_LINK

#include <inttypes.h>
#include <stdbool.h>
#include <time.h>

#include "link_virtual.h"
typedef struct Urzadzenie Urzadzenie;
typedef unsigned int uint;

/* typ reprezentujący timestamp. */
typedef uint16_t tstamp_t;


/* Moduł używa wartości MTU. Domyślnie 1500, ale dobrze, żeby mozna było to
 * zmienić dodając do opcji kompilacji np. -DMTU=1500 . Nazwa HWMTU odnosi się
 * do MTU na poziomie sprzętowym czyli MTU powiększone o rozmiar SSID
 * i timestampu. */
#ifndef MTU
#define HWMTU 1497
#else
#define HWMTU MTU + sizeof( tstamp_t ) + 1
#endif

/* Odstęp między iteracjami symulacji w nanosekundach. */
#ifndef SIM_INTERVAL
#define SIM_INTERVAL 50000
#endif


/* Parametry symulacji:
 * Jednostka czasu w ns: */
#define TIME_UNIT 1000

/* Szybkość transmisji (?? :)) */
#define TSPEED 14

/* Wielkość szczeliny czasowej i maksymalny backoff (w szczelinach czasowych) */
#define TIME_SLOT 20
#define MAX_BACKOFF 4

/* IFSy i rozmiar ACKa */
#define IFS_TIME 75
#define DIFS_TIME 50
#define SIFS_TIME 10
#define ACK_BYTES 14

#define DEFAULT_TIMER CLOCK_PROCESS_CPUTIME_ID

/* Struktura reprezentująca jedną ramkę bufora. */
typedef struct{
    char    content[HWMTU];      /* treść ramki. */
    size_t  size;              /* rozmiar ramki. */
} FrameBuffer;

/* Struktura przechowująca dane symulacji dostępu do łącza. */
typedef struct{
    size_t  ifaces_in_network, /* Liczba interfejsów korzystających z łącza. */
            ifaces_in_node;    /* Liczba interfejsów w obrębie węzła. */
    uint    timer, itimer;    /* prywatne */
    Urzadzenie *outputs;       /* Lista interfejsów w obrębie węzła. */

    FrameBuffer *frame_buffer; /* Bufor przechowujący ramki do wysłania. */
    uint    sim_time;          /* Czas trwania symulacji. */

    uint    processed_frames;  /* Licznik przetworzonych ramek. */
    uint    simulation_time,   /* Czas procesora poświęcony na symulację. */
            simulated_time;    /* Suma czasów wyliczonych przez symulator */
}Link;

/* Zaalokuj strukturę symulacji dostępu do łącza */
Link *new_link_sim( size_t      ifaces_in_network,
                    size_t      ifaces_in_node,
                    Urzadzenie  *outputs );

/* Zwolnij strukturę symulatora. */
void end_link_sim( Link *handle );

/* Wykonaj symulacje dla obecnego stanu bufora. */
bool link_simulate( Link *handle );

/* Wprowadź ramkę do bufora. Trzeba wepchnąć do niej SSID i timestamp. */
#endif
